#include "timer_manager.h"
#include "logger.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t total_size = size * nmemb;
    char **response_ptr = (char **)userp;

    *response_ptr = realloc(*response_ptr, total_size + 1);
    if (*response_ptr == NULL) {
        return 0;
    }

    memcpy(*response_ptr, contents, total_size);
    (*response_ptr)[total_size] = '\0';

    return total_size;
}

// 工作线程函数
static void *timer_worker_thread(void *arg) {
    timer_manager_t *timer = (timer_manager_t *)arg;
    if (!timer) {
        return NULL;
    }

    LOG_INFO("Timer worker thread started");

    while (timer->running) {
        time_t current_time = time(NULL);

        pthread_mutex_lock(&timer->mutex);

        timer_task_t *task = timer->tasks;
        while (task) {
            if (task->status == TIMER_STATUS_ACTIVE) {
                bool should_execute = false;

                switch (task->type) {
                case TIMER_TYPE_INTERVAL: {
                    if (task->last_executed == 0) {
                        // 第一次执行
                        should_execute = true;
                    } else {
                        time_t elapsed_ms = (current_time - task->last_executed) * 1000;
                        if (elapsed_ms >= task->config.interval.interval_ms) {
                            should_execute = true;
                        }
                    }
                    break;
                }

                case TIMER_TYPE_CRON: {
                    if (task->config.cron.cron_expr) {
                        if (cron_check_time(task->config.cron.cron_expr, current_time)) {
                            // 避免在同一秒内重复执行
                            if (task->last_executed != current_time) {
                                should_execute = true;
                            }
                        }
                    }
                    break;
                }

                case TIMER_TYPE_ONESHOT: {
                    if (current_time >= task->config.oneshot.execute_time) {
                        should_execute = true;
                    }
                    break;
                }
                }

                if (should_execute) {
                    // 检查执行次数限制
                    if (task->max_executions != -1 &&
                        task->execution_count >= task->max_executions) {
                        task->status = TIMER_STATUS_COMPLETED;
                        LOG_INFO("Task '%s' completed after %d executions",
                                 task->name, task->execution_count);
                    } else {
                        // 执行回调函数
                        LOG_DEBUG("Executing timer task: %s", task->name);

                        // 在锁外执行回调，避免阻塞其他任务
                        timer_task_t *task_copy = task;
                        pthread_mutex_unlock(&timer->mutex);

                        // 执行回调
                        if (task_copy->callback) {
                            task_copy->callback(task_copy->callback_arg);
                        }

                        pthread_mutex_lock(&timer->mutex);

                        // 更新任务状态
                        task->last_executed = current_time;
                        task->execution_count++;

                        // 计算下一次执行时间
                        switch (task->type) {
                        case TIMER_TYPE_INTERVAL:
                            task->next_execution = current_time +
                                                   (task->config.interval.interval_ms / 1000);
                            break;

                        case TIMER_TYPE_CRON:
                            if (task->config.cron.cron_expr) {
                                task->next_execution = cron_next_time(
                                    task->config.cron.cron_expr, current_time);
                            }
                            break;

                        case TIMER_TYPE_ONESHOT:
                            task->status = TIMER_STATUS_COMPLETED;
                            task->next_execution = 0;
                            break;
                        }

                        // 发送定时器事件
                        if (timer->event_loop) {
                            json_t *event_data = json_object();
                            json_object_set_new(event_data, "task_name",
                                                json_string(task->name));
                            json_object_set_new(event_data, "execution_count",
                                                json_integer(task->execution_count));
                            json_object_set_new(event_data, "timestamp",
                                                json_integer(current_time));

                            // 注意：这里需要确保event_create函数存在
                            // 如果不存在，可以暂时注释掉这部分
                            /*
                            event_t *event = event_create(EVENT_TIMER_TRIGGER,
                                                         event_data,
                                                         sizeof(json_t*),
                                                         NULL);
                            if (event) {
                                event_loop_send_event(timer->event_loop, event);
                                event_destroy(event);
                            }
                            */
                            json_decref(event_data);
                        }
                    }
                }
            }

            task = task->next;
        }

        pthread_mutex_unlock(&timer->mutex);

        // 休眠检查间隔时间
        usleep(timer->check_interval_ms * 1000);
    }

    LOG_INFO("Timer worker thread stopped");
    return NULL;
}

int timer_manager_init(timer_manager_t *timer, event_loop_t *event_loop) {
    if (!timer || !event_loop) {
        return ERROR_INVALID_PARAM;
    }
    
    memset(timer, 0, sizeof(timer_manager_t));
    
    if (pthread_mutex_init(&timer->mutex, NULL) != 0) {
        return ERROR_THREAD_CREATE;
    }
    
    timer->event_loop = event_loop;
    timer->check_interval_ms = 100; // 默认100ms检查间隔
    timer->running = false;
    timer->tasks = NULL;
    timer->total_tasks = 0;
    timer->active_tasks = 0;
    
    LOG_INFO("Timer manager initialized");
    return SUCCESS;
}

int timer_manager_set_check_interval(timer_manager_t *timer, int interval_ms) {
    if (!timer || interval_ms <= 0) {
        return ERROR_INVALID_PARAM;
    }
    
    timer->check_interval_ms = interval_ms;
    return SUCCESS;
}

int timer_manager_add_interval_task(timer_manager_t *timer, const char *name, 
                                   int interval_ms, timer_callback_t callback, 
                                   void *arg, int max_executions) {
    if (!timer || !name || !callback || interval_ms <= 0) {
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    // 检查任务是否已存在
    timer_task_t *existing = timer->tasks;
    while (existing) {
        if (strcmp(existing->name, name) == 0) {
            pthread_mutex_unlock(&timer->mutex);
            LOG_ERROR("Timer task '%s' already exists", name);
            return ERROR_INVALID_PARAM;
        }
        existing = existing->next;
    }
    
    // 创建新任务
    timer_task_t *task = calloc(1, sizeof(timer_task_t));
    if (!task) {
        pthread_mutex_unlock(&timer->mutex);
        return ERROR_MEMORY_ALLOC;
    }
    
    task->name = strdup(name);
    task->type = TIMER_TYPE_INTERVAL;
    task->status = TIMER_STATUS_ACTIVE;
    task->callback = callback;
    task->callback_arg = arg;
    task->config.interval.interval_ms = interval_ms;
    task->max_executions = max_executions;
    task->last_executed = 0;
    task->execution_count = 0;
    task->max_errors = 3; // 默认最大错误数
    
    // 添加到链表头部
    task->next = timer->tasks;
    timer->tasks = task;
    timer->total_tasks++;
    timer->active_tasks++;
    
    pthread_mutex_unlock(&timer->mutex);
    
    LOG_INFO("Added interval timer task: %s (interval: %dms)", name, interval_ms);
    return SUCCESS;
}

int timer_manager_add_cron_task(timer_manager_t *timer, const char *name, 
                               const char *cron_expression, timer_callback_t callback, 
                               void *arg, int max_executions) {
    if (!timer || !name || !cron_expression || !callback) {
        return ERROR_INVALID_PARAM;
    }
    
    // 解析cron表达式
    cron_expr_t *cron_expr = cron_parse(cron_expression);
    if (!cron_expr) {
        LOG_ERROR("Failed to parse cron expression: %s", cron_expression);
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    // 检查任务是否已存在
    timer_task_t *existing = timer->tasks;
    while (existing) {
        if (strcmp(existing->name, name) == 0) {
            cron_free(cron_expr);
            pthread_mutex_unlock(&timer->mutex);
            LOG_ERROR("Timer task '%s' already exists", name);
            return ERROR_INVALID_PARAM;
        }
        existing = existing->next;
    }
    
    // 创建新任务
    timer_task_t *task = calloc(1, sizeof(timer_task_t));
    if (!task) {
        cron_free(cron_expr);
        pthread_mutex_unlock(&timer->mutex);
        return ERROR_MEMORY_ALLOC;
    }
    
    task->name = strdup(name);
    task->type = TIMER_TYPE_CRON;
    task->status = TIMER_STATUS_ACTIVE;
    task->callback = callback;
    task->callback_arg = arg;
    task->config.cron.cron_expression = strdup(cron_expression);
    task->config.cron.cron_expr = cron_expr;
    task->config.cron.timezone = strdup("UTC");
    task->max_executions = max_executions;
    task->last_executed = 0;
    task->execution_count = 0;
    task->max_errors = 3;
    
    // 计算下一次执行时间
    task->next_execution = cron_next_time(cron_expr, time(NULL));
    
    // 添加到链表头部
    task->next = timer->tasks;
    timer->tasks = task;
    timer->total_tasks++;
    timer->active_tasks++;
    
    pthread_mutex_unlock(&timer->mutex);
    
    LOG_INFO("Added cron timer task: %s (expression: %s)", name, cron_expression);
    return SUCCESS;
}

int timer_manager_add_oneshot_task(timer_manager_t *timer, const char *name, 
                                  time_t execute_time, timer_callback_t callback, 
                                  void *arg) {
    if (!timer || !name || !callback || execute_time <= time(NULL)) {
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    // 检查任务是否已存在
    timer_task_t *existing = timer->tasks;
    while (existing) {
        if (strcmp(existing->name, name) == 0) {
            pthread_mutex_unlock(&timer->mutex);
            LOG_ERROR("Timer task '%s' already exists", name);
            return ERROR_INVALID_PARAM;
        }
        existing = existing->next;
    }
    
    // 创建新任务
    timer_task_t *task = calloc(1, sizeof(timer_task_t));
    if (!task) {
        pthread_mutex_unlock(&timer->mutex);
        return ERROR_MEMORY_ALLOC;
    }
    
    task->name = strdup(name);
    task->type = TIMER_TYPE_ONESHOT;
    task->status = TIMER_STATUS_ACTIVE;
    task->callback = callback;
    task->callback_arg = arg;
    task->config.oneshot.execute_time = execute_time;
    task->max_executions = 1; // 一次性任务只能执行一次
    task->last_executed = 0;
    task->execution_count = 0;
    task->next_execution = execute_time;
    task->max_errors = 1; // 一次性任务不允许错误
    
    // 添加到链表头部
    task->next = timer->tasks;
    timer->tasks = task;
    timer->total_tasks++;
    timer->active_tasks++;
    
    pthread_mutex_unlock(&timer->mutex);
    
    LOG_INFO("Added oneshot timer task: %s (execute_time: %ld)", name, execute_time);
    return SUCCESS;
}

int timer_manager_remove_task(timer_manager_t *timer, const char *name) {
    if (!timer || !name) {
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    timer_task_t *prev = NULL;
    timer_task_t *current = timer->tasks;
    
    while (current) {
        if (strcmp(current->name, name) == 0) {
            if (prev) {
                prev->next = current->next;
            } else {
                timer->tasks = current->next;
            }
            
            // 释放资源
            if (current->type == TIMER_TYPE_CRON) {
                if (current->config.cron.cron_expression) {
                    free(current->config.cron.cron_expression);
                }
                if (current->config.cron.cron_expr) {
                    cron_free(current->config.cron.cron_expr);
                }
                if (current->config.cron.timezone) {
                    free(current->config.cron.timezone);
                }
            }
            
            if (current->name) {
                free(current->name);
            }
            
            timer->total_tasks--;
            if (current->status == TIMER_STATUS_ACTIVE) {
                timer->active_tasks--;
            }
            
            free(current);
            
            pthread_mutex_unlock(&timer->mutex);
            LOG_INFO("Removed timer task: %s", name);
            return SUCCESS;
        }
        
        prev = current;
        current = current->next;
    }
    
    pthread_mutex_unlock(&timer->mutex);
    LOG_WARN("Timer task '%s' not found", name);
    return ERROR_INVALID_PARAM;
}

int timer_manager_pause_task(timer_manager_t *timer, const char *name) {
    if (!timer || !name) {
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    timer_task_t *task = timer->tasks;
    while (task) {
        if (strcmp(task->name, name) == 0) {
            if (task->status == TIMER_STATUS_ACTIVE) {
                task->status = TIMER_STATUS_PAUSED;
                timer->active_tasks--;
                pthread_mutex_unlock(&timer->mutex);
                LOG_INFO("Paused timer task: %s", name);
                return SUCCESS;
            } else {
                pthread_mutex_unlock(&timer->mutex);
                LOG_WARN("Timer task '%s' is not active", name);
                return ERROR_INVALID_PARAM;
            }
        }
        task = task->next;
    }
    
    pthread_mutex_unlock(&timer->mutex);
    LOG_WARN("Timer task '%s' not found", name);
    return ERROR_INVALID_PARAM;
}

int timer_manager_resume_task(timer_manager_t *timer, const char *name) {
    if (!timer || !name) {
        return ERROR_INVALID_PARAM;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    timer_task_t *task = timer->tasks;
    while (task) {
        if (strcmp(task->name, name) == 0) {
            if (task->status == TIMER_STATUS_PAUSED) {
                task->status = TIMER_STATUS_ACTIVE;
                timer->active_tasks++;
                pthread_mutex_unlock(&timer->mutex);
                LOG_INFO("Resumed timer task: %s", name);
                return SUCCESS;
            } else {
                pthread_mutex_unlock(&timer->mutex);
                LOG_WARN("Timer task '%s' is not paused", name);
                return ERROR_INVALID_PARAM;
            }
        }
        task = task->next;
    }
    
    pthread_mutex_unlock(&timer->mutex);
    LOG_WARN("Timer task '%s' not found", name);
    return ERROR_INVALID_PARAM;
}

timer_task_t *timer_manager_find_task(timer_manager_t *timer, const char *name) {
    if (!timer || !name) {
        return NULL;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    timer_task_t *task = timer->tasks;
    while (task) {
        if (strcmp(task->name, name) == 0) {
            pthread_mutex_unlock(&timer->mutex);
            return task;
        }
        task = task->next;
    }
    
    pthread_mutex_unlock(&timer->mutex);
    return NULL;
}

json_t *timer_manager_get_task_status(timer_manager_t *timer, const char *name) {
    timer_task_t *task = timer_manager_find_task(timer, name);
    if (!task) {
        return NULL;
    }
    
    json_t *status = json_object();
    json_object_set_new(status, "name", json_string(task->name));
    json_object_set_new(status, "type", json_string(timer_type_to_string(task->type)));
    json_object_set_new(status, "status", json_string(timer_status_to_string(task->status)));
    json_object_set_new(status, "execution_count", json_integer(task->execution_count));
    json_object_set_new(status, "last_executed", json_integer(task->last_executed));
    json_object_set_new(status, "next_execution", json_integer(task->next_execution));
    json_object_set_new(status, "max_executions", json_integer(task->max_executions));
    
    // 类型特定的配置
    switch (task->type) {
        case TIMER_TYPE_INTERVAL:
            json_object_set_new(status, "interval_ms", 
                               json_integer(task->config.interval.interval_ms));
            break;
            
        case TIMER_TYPE_CRON:
            json_object_set_new(status, "cron_expression", 
                               json_string(task->config.cron.cron_expression));
            json_object_set_new(status, "timezone", 
                               json_string(task->config.cron.timezone));
            break;
            
        case TIMER_TYPE_ONESHOT:
            json_object_set_new(status, "execute_time", 
                               json_integer(task->config.oneshot.execute_time));
            break;
    }
    
    return status;
}

json_t *timer_manager_get_all_tasks_status(timer_manager_t *timer) {
    if (!timer) {
        return NULL;
    }
    
    pthread_mutex_lock(&timer->mutex);
    
    json_t *tasks_array = json_array();
    timer_task_t *task = timer->tasks;
    
    while (task) {
        json_t *task_status = json_object();
        json_object_set_new(task_status, "name", json_string(task->name));
        json_object_set_new(task_status, "type", json_string(timer_type_to_string(task->type)));
        json_object_set_new(task_status, "status", json_string(timer_status_to_string(task->status)));
        json_object_set_new(task_status, "execution_count", json_integer(task->execution_count));
        json_object_set_new(task_status, "last_executed", json_integer(task->last_executed));
        json_object_set_new(task_status, "next_execution", json_integer(task->next_execution));
        
        json_array_append_new(tasks_array, task_status);
        task = task->next;
    }
    
    json_t *result = json_object();
    json_object_set_new(result, "total_tasks", json_integer(timer->total_tasks));
    json_object_set_new(result, "active_tasks", json_integer(timer->active_tasks));
    json_object_set_new(result, "tasks", tasks_array);
    
    pthread_mutex_unlock(&timer->mutex);
    return result;
}

void timer_manager_start(timer_manager_t *timer) {
    if (!timer || timer->running) {
        return;
    }
    
    timer->running = true;
    
    if (pthread_create(&timer->thread, NULL, timer_worker_thread, timer) != 0) {
        LOG_ERROR("Failed to create timer worker thread");
        timer->running = false;
        return;
    }
    
    LOG_INFO("Timer manager started");
}

void timer_manager_stop(timer_manager_t *timer) {
    if (!timer || !timer->running) {
        return;
    }
    
    timer->running = false;
    
    // 等待工作线程结束
    if (timer->thread) {
        pthread_join(timer->thread, NULL);
        timer->thread = 0;
    }
    
    LOG_INFO("Timer manager stopped");
}

void timer_manager_destroy(timer_manager_t *timer) {
    if (!timer) {
        return;
    }
    
    timer_manager_stop(timer);
    
    pthread_mutex_lock(&timer->mutex);
    
    // 释放所有任务
    timer_task_t *task = timer->tasks;
    while (task) {
        timer_task_t *next = task->next;
        
        // 释放资源
        if (task->type == TIMER_TYPE_CRON) {
            if (task->config.cron.cron_expression) {
                free(task->config.cron.cron_expression);
            }
            if (task->config.cron.cron_expr) {
                cron_free(task->config.cron.cron_expr);
            }
            if (task->config.cron.timezone) {
                free(task->config.cron.timezone);
            }
        }
        
        if (task->name) {
            free(task->name);
        }
        
        free(task);
        task = next;
    }
    
    timer->tasks = NULL;
    timer->total_tasks = 0;
    timer->active_tasks = 0;
    
    pthread_mutex_unlock(&timer->mutex);
    pthread_mutex_destroy(&timer->mutex);
    
    LOG_INFO("Timer manager destroyed");
}

const char *timer_type_to_string(timer_type_t type) {
    switch (type) {
        case TIMER_TYPE_INTERVAL: return "interval";
        case TIMER_TYPE_CRON: return "cron";
        case TIMER_TYPE_ONESHOT: return "oneshot";
        default: return "unknown";
    }
}

const char *timer_status_to_string(timer_status_t status) {
    switch (status) {
        case TIMER_STATUS_ACTIVE: return "active";
        case TIMER_STATUS_PAUSED: return "paused";
        case TIMER_STATUS_COMPLETED: return "completed";
        case TIMER_STATUS_ERROR: return "error";
        default: return "unknown";
    }
}
